#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

//T类型参数，kSize非类型参数
template <typename T = int, size_t kSize = 10>
class Stack
{
public:
    Stack()
    : _top(-1)
    , _data(new T[kSize]())
    {
        cout << "Stack()" << endl;
    }

    ~Stack();

    bool empty() const;
    bool full() const;
    void push(const T &value);
    void pop();
    T top() const;

private:
    int _top;
    T *_data;
};

template <typename T, size_t kSize>
Stack<T, kSize>::~Stack()
{
    cout << "~Stack()" << endl;
    if(_data)
    {
        delete [] _data;
        _data = nullptr;
    }
}

template <typename T, size_t kSize>
bool Stack<T, kSize>::empty() const
{
    return (-1 == _top);
}

template <typename T, size_t kSize>
bool Stack<T, kSize>::full() const
{
    return (_top == kSize - 1);
}

template <typename T, size_t kSize>
void Stack<T, kSize>::push(const T &value)
{
    if(!full())
    {
        _data[++_top] = value;
    }
    else
    {
        cout << "The stack is full" << endl;
        return;
    }
}

template <typename T, size_t kSize>
void Stack<T, kSize>::pop()
{
    if(!empty())
    {
        --_top;
    }
    else
    {
        cout << "The Stack is empty" << endl;
        return;
    }
}

template <typename T, size_t kSize>
T Stack<T, kSize>::top() const
{
    return _data[_top];
}

void test()
{
    Stack<int, 20> st;//st是栈对象
    cout << "栈是不是空的 ? " << st.empty() << endl;
    st.push(1);
    cout << "栈是不是满的 ? " << st.full() << endl;

    for(int idx = 2; idx < 30; ++idx)
    {
        st.push(idx);
    }
    cout << "栈是不是满的 ? " << st.full() << endl;
    //遍历Stack
    while(!st.empty())
    {
        cout << st.top() << "  ";
        st.pop();
    }
    cout << endl;
    cout << "栈是不是空的 ? " << st.empty() << endl;
}

void test2()
{
    Stack<string, 20> st;//st是栈对象
    cout << "栈是不是空的 ? " << st.empty() << endl;
    st.push(string("aa"));
    cout << "栈是不是满的 ? " << st.full() << endl;

    for(int idx = 1; idx < 15; ++idx)
    {
        st.push(string(2, 'a' + idx));//2, b c d 
    }
    cout << "栈是不是满的 ? " << st.full() << endl;
    //遍历Stack
    while(!st.empty())
    {
        cout << st.top() << "  ";
        st.pop();
    }
    cout << endl;
    cout << "栈是不是空的 ? " << st.empty() << endl;
}
int main(int argc, char **argv)
{
    test2();
    return 0;
}

